//Matthew Landrum
//Assignment 3.cpp

#include <time.h>
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

struct Card {
	string value;	//Card's value in text
	string suit;	//Card's suit
	int numVal;		//Card's value as an integer (allows for comparison)
};

class Deck
{
public:
	void makeDeck();				//create standard deck of 52 cards
	void outputDeck();				//output contents of deck
	Card dealCard();				//return top card and remove from deck
	Deck dealCard(int numOfCards);	//return deck of top numOfCards cards and remove from deck
	void addCard(Card myCard);		//add card to bottom of deck
	void shuffle();					//randomize deck contents
private:
	Card cards[52];					//Array of cards.  Max Size: 52.  Top of deck = cards[curSize-1]
	int curSize = 0;				//Current number of cards in deck. Default size: 0
};


int main()
{
	Deck mainDeck;
	mainDeck.makeDeck();
	mainDeck.outputDeck();
	mainDeck.shuffle();
	mainDeck.outputDeck();

	Card outputCard = mainDeck.dealCard();

	cout << "Your card is the " << outputCard.value << " of " << outputCard.suit << endl << endl;

	Deck outDeck = mainDeck.dealCard(5);

	cout << "New Deck: " << endl;
	outDeck.outputDeck();
	outDeck.shuffle();
	outDeck.outputDeck();
}

void Deck::makeDeck()
//postcondition: a deck of cards of size "size"
{
	int suitNum;
	for (int i = 0; i < 52; i++) {
		cards[i].numVal = (i % 13) + 2;	//i% 13 gives 0-12, need to adjust up to min value of 2
		suitNum = i % 4;				//gives 0-3, or 4 different suits
		switch (suitNum) {
		case 0:
			cards[i].suit = "spades";
			break;
		case 1:
			cards[i].suit = "diamonds";
			break;
		case 2:
			cards[i].suit = "clubs";
			break;
		case 3:
			cards[i].suit = "hearts";
			break;
		}

		//set value for number cards
		if (cards[i].numVal < 11) {
			cards[i].value = to_string(cards[i].numVal);
		}
		//set value for cards greater than 9
		else {
			switch (cards[i].numVal) {
			case 11:
				cards[i].value = "J";
				break;
			case 12:
				cards[i].value = "Q";
				break;
			case 13:
				cards[i].value = "K";
				break;
			case 14:	//Aces high
				cards[i].value = "A";
				break;
			}
		}

		//track number of cards added
		curSize++;
	}
}

void Deck::outputDeck()
{
	//output intro
	cout << "Your cards are:" << endl;
	//output each card starting with top of deck
	for (int i = curSize-1; i >= 0; i--) {
		cout << cards[i].value << " of " << cards[i].suit << endl;
	}
	//blank line
	cout << endl;
}

Card Deck::dealCard()
{
	//reduce deck size
	curSize--;
	//return card on top of the array
	Card myCard = cards[curSize];
	return myCard;
}

Deck Deck::dealCard(int numOfCards)
{
	Deck myDeck;
	for (int i = 0; i < numOfCards; i++) {
		curSize--;
		myDeck.addCard(cards[curSize]);
	}
	return myDeck;
}

void Deck::addCard(Card myCard) {
	//for each card, starting at the top of the deck, going to the bottom + 1
	for (int i = curSize; i > 0; i--) {
		//shift one cell right in the array
		cards[i] = cards[i - 1];
	}
	//add new card to bottom of deck
	cards[0] = myCard;
	curSize++;
}

void Deck::shuffle() {
	//set random seed
	srand(time(0));

	//for each card up to current size
	for (int i = 0; i < curSize; i++) {
		//find random postiion between 0 and curSize -1
		int position = rand() % curSize;
		
		//swap card in random position with current card
		Card temp = cards[position];
		cards[position] = cards[i];
		cards[i] = temp;
	}
}